<template>
  <div class="app-container">
    <!-- 用户名输入 (仅在未设置用户名时显示) -->
    <div v-if="!username" class="login-container">
      <h2>聊天功能需要登录</h2>
      <button @click="goToLogin">去登录</button>
    </div>

    <!-- 主界面 (设置用户名后显示) -->
    <div v-else class="main-container">
      <!-- 显示路由视图 -->
      <router-view 
        v-slot="{ Component }"
      >
        <component 
          :is="Component" 
          :username="username"
          :chat-rooms="chatRooms"
          :selected-room-id="currentRoom ? currentRoom.id : ''"
          :room-messages="roomMessages"
          :websocket="ws"
          :messages="currentRoomMessages"
          :current-room="currentRoom"
          @select-room="handleSelectRoom"
          @go-back="handleGoBack"
          @websocket-reconnected="handleWebsocketReconnected"
        />
      </router-view>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'

// 获取路由
const router = useRouter()
const route = useRoute()

// localStorage键名常量
const STORAGE_KEYS = {
  CHAT_HISTORY: 'chat_history',
  USERNAME: 'username'
}

// 状态变量
const username = ref('')
const chatRooms = ref([])
const currentRoom = ref(null)
const roomMessages = ref({})
const ws = ref(null)
const activeRooms = ref(new Set()) // 跟踪用户已加入的房间
const userListUpdateTimer = ref(null) // 定时获取用户列表的定时器
const reconnectAttempts = ref(0) // 重连尝试次数
const maxReconnectAttempts = 10 // 最大重连次数

// 跳转到登录页面
function goToLogin() {
  router.push('/login')
}

// 加载本地存储的聊天历史
function loadLocalStorage() {
  try {
    // 获取用户名
    const savedUsername = localStorage.getItem(STORAGE_KEYS.USERNAME)
    if (savedUsername) {
      username.value = savedUsername
    }
    
    // 加载聊天历史
    const savedMessages = localStorage.getItem(STORAGE_KEYS.CHAT_HISTORY)
    if (savedMessages) {
      roomMessages.value = JSON.parse(savedMessages)
    }
    
    console.log('已从本地存储加载聊天历史')
  } catch (error) {
    console.error('加载本地存储数据失败:', error)
  }
}

// 保存聊天历史到本地存储
function saveLocalStorage() {
  try {
    // 保存聊天历史
    localStorage.setItem(STORAGE_KEYS.CHAT_HISTORY, JSON.stringify(roomMessages.value))
  } catch (error) {
    console.error('保存数据到本地存储失败:', error)
  }
}

// 当前房间的消息
const currentRoomMessages = computed(() => {
  if (!currentRoom.value) return []
  
  // 如果是私聊，需要使用特殊的ID格式
  if (currentRoom.value.type === 'private') {
    const privateRoomId = getPrivateRoomId(username.value, currentRoom.value.id)
    return roomMessages.value[privateRoomId] || []
  }
  
  return roomMessages.value[currentRoom.value.id] || []
})

// 生成私聊房间ID (确保两人之间的ID一致，无论谁发起私聊)
function getPrivateRoomId(user1, user2) {
  return [user1, user2].sort().join('_')
}

// 开始定时获取用户列表
function startUserListUpdateTimer() {
  // 清除之前的定时器（如果有）
  if (userListUpdateTimer.value) {
    clearInterval(userListUpdateTimer.value)
  }
  
  // 设置新的定时器，每10秒获取一次最新用户列表
  userListUpdateTimer.value = setInterval(() => {
    if (ws.value && ws.value.readyState === WebSocket.OPEN) {
      requestUserList()
    }
  }, 10000) // 10秒
}

// 请求获取最新用户列表
function requestUserList() {
  if (ws.value && ws.value.readyState === WebSocket.OPEN) {
    ws.value.send(JSON.stringify({
      type: 'getUserList'
    }))
  }
}

// 处理子组件的WebSocket重连事件
function handleWebsocketReconnected(newWebSocket) {
  console.log('接收到WebSocket重连事件')
  
  // 更新WebSocket引用
  if (ws.value) {
    // 清理旧的WebSocket连接
    try {
      ws.value.close()
    } catch (e) {
      console.error('关闭旧WebSocket连接失败:', e)
    }
  }
  
  // 使用新的WebSocket连接
  ws.value = newWebSocket
  
  // 重新设置WebSocket事件处理
  setupWebSocketEvents(newWebSocket)
  
  // 重置重连计数
  reconnectAttempts.value = 0
  
  // 重新启动用户列表更新定时器
  startUserListUpdateTimer()
  
  console.log('WebSocket重连完成')
}

// 设置WebSocket事件处理
function setupWebSocketEvents(websocket) {
  websocket.onmessage = function(event) {
    const data = JSON.parse(event.data)
    
    switch(data.type) {
      case 'roomList':
        // 接收群聊和用户列表
        chatRooms.value = data.data
        break;
      
      case 'history':
        // 接收历史消息
        if (currentRoom.value) {
          let roomId = currentRoom.value.id
          
          // 如果是私聊，使用特殊的ID格式
          if (currentRoom.value.type === 'private') {
            roomId = getPrivateRoomId(username.value, currentRoom.value.id)
          }
          
          if (!roomMessages.value[roomId]) {
            roomMessages.value[roomId] = []
          }
          roomMessages.value[roomId] = data.data
          
          // 保存更新后的消息到本地存储
          saveLocalStorage()
        }
        break;
      
      case 'message':
        // 接收新消息
        const message = data.data
        let roomId = message.roomId
        
        // 如果是私聊消息，使用特殊的ID格式
        if (message.roomType === 'private') {
          const otherUser = message.username === username.value ? message.roomId : message.username
          roomId = getPrivateRoomId(username.value, otherUser)
        }
        
        if (roomId) {
          // 确保该房间的消息数组已初始化
          if (!roomMessages.value[roomId]) {
            roomMessages.value[roomId] = []
          }
          
          // 添加消息到相应房间
          roomMessages.value[roomId].push(message)
          
          // 保存更新后的消息到本地存储
          saveLocalStorage()
        }
        break;
        
      case 'pong':
        // 接收心跳响应
        console.log('收到服务器心跳响应:', data.timestamp)
        break;
    }
  }
  
  websocket.onerror = function(error) {
    console.error('WebSocket错误:', error)
  }
  
  websocket.onclose = function() {
    console.log('WebSocket连接关闭')
    // 连接关闭后，尝试重新连接
    attemptReconnect()
  }
}

// 连接WebSocket
function connectWebSocket() {
  // 使用动态IP地址，通过window.location.hostname获取当前主机地址
  // 这样在同一局域网内的不同设备都可以连接到同一个WebSocket服务器
  const host = window.location.hostname; // 获取当前主机名
  ws.value = new WebSocket(`ws://${host}:3000`);
  
  ws.value.onopen = function() {
    console.log('WebSocket连接成功')
    
    // 连接成功后发送登录消息
    ws.value.send(JSON.stringify({
      type: 'login',
      username: username.value
    }))
    
    // 重置重连计数
    reconnectAttempts.value = 0
    
    // 设置定时器，定期获取最新的用户列表
    startUserListUpdateTimer()
  }
  
  // 设置WebSocket事件处理
  setupWebSocketEvents(ws.value)
}

// 尝试重新连接
function attemptReconnect() {
  // 如果超过最大重连次数，停止尝试
  if (reconnectAttempts.value >= maxReconnectAttempts) {
    console.log('超过最大重连次数，不再尝试重连')
    return
  }
  
  reconnectAttempts.value++
  console.log(`尝试重连 (${reconnectAttempts.value}/${maxReconnectAttempts})`)
  
  // 延迟重连，避免立即尝试
  setTimeout(connectWebSocket, 3000) // 3秒后重连
}

// 选择群聊或私聊
function handleSelectRoom(room) {
  currentRoom.value = room
  
  // 记录用户已加入的房间
  activeRooms.value.add(room.id)
  
  // 发送加入群聊或开始私聊的消息
  ws.value.send(JSON.stringify({
    type: 'join',
    username: username.value,
    roomId: room.id,
    roomType: room.type // 'group' 或 'private'
  }))
  
  // 导航到聊天详情页面
  router.push(`/chat/detail/${room.id}`)
}

// 返回群聊列表
function handleGoBack() {
  // 导航回聊天列表页面
  router.push('/chat')
  
  // 请求最新的用户列表
  requestUserList()
}

// 在组件挂载后
onMounted(() => {
  // 从本地存储加载数据
  loadLocalStorage()
  
  // 如果已登录，连接WebSocket并开始定时获取用户列表
  if (username.value) {
    connectWebSocket()
    startUserListUpdateTimer()
    
    // 如果当前路径是聊天根路径，自动导航到聊天列表
    if (route.path === '/chat') {
      router.push('/chat')
    }
  }
})

// 在组件卸载前
onUnmounted(() => {
  if (userListUpdateTimer.value) {
    clearInterval(userListUpdateTimer.value)
  }
  
  // 保存聊天历史到本地存储
  saveLocalStorage()
})

// 监听路由变化，在路由变化时保存数据
watch(() => route.path, () => {
  saveLocalStorage()
})
</script>

<style>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.app-container {
  font-family: Arial, sans-serif;
  height: 100vh;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #f0f0f0;
  overflow: hidden; /* 防止出现滚动条 */
  box-sizing: border-box; /* 确保padding和border不会增加元素总宽度 */
  position: relative;
}

/* 登录界面 */
.login-container {
  background-color: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  text-align: center;
  width: 300px;
}

.login-container h2 {
  margin-bottom: 20px;
  color: #333;
}

.login-container input {
  width: 100%;
  padding: 10px;
  margin-bottom: 15px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.login-container button {
  background-color: #07C160;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 4px;
  cursor: pointer;
}

/* 主界面 */
.main-container {
  width: 100%;
  height: 100%;
  background-color: white;
  display: flex;
  overflow: hidden; /* 防止出现滚动条 */
  box-sizing: border-box;
  position: relative;
}
</style>